/**
    @file logger.cpp
    @brief Logger
*/
#include "logger.hpp"

template<> pm3::LOGGER* Ogre::Singleton<pm3::LOGGER>::ms_Singleton = 0;
pm3::LOGGER pm3::g_logger;

pm3::LOGGER::LOGGER() {
    // Set the default by default
    m_file = "gamelog.txt";
}

pm3::LOGGER::~LOGGER() {
    m_file = "";
    m_sections.clear();
    m_contents.clear();
}

int pm3::LOGGER::get_section( const std::string &r_title ) {
    // Perhaps we already have such a section?
    for (size_t i=0; i<m_sections.size(); i++) {
        if (m_sections [i] == r_title)
            return i;
    }
    // Noes? Add it
    m_sections.push_back( r_title );
    m_contents.push_back( "" );
    return( m_sections.size() - 1 );
}

bool pm3::LOGGER::report( const std::string &r_section, const char *fmt, ... ) {
	va_list    ap;
	char       *buf = NULL;
	char       *newbuf = NULL;
	std::string buf2;
	int			buffered = 0;
	int			size = 1024;
    FILE       *file = NULL;
    int         i_section = get_section( r_section );

    // Try to open the logfile
    file = fopen( m_file.c_str(), "wt+" );
    // File couldn't be opened?
    if (!file)
        return false;

	// Nothing to be written?
	if (fmt == NULL)
		return true;

    // Is section number ok?
    if (i_section < 0 || i_section >= (int) m_sections.size())
        return false;

    // Allocate memory for the buffer
	buf = (char *) malloc ( size * sizeof (char) );

	// Basically a safe vsprintf
	while (1) {
		/* Try to print in the allocated space. */
		va_start( ap, fmt );

		buffered = vsnprintf( buf, size, fmt, ap );

		va_end( ap );

		/* If that worked, return the string. */
		if (buffered > -1 && buffered < size)
			break;
		/* Else try again with more space. */
		if (buffered > -1)    /* glibc 2.1 */
			size = buffered + 1; /* precisely what is needed */
		else           /* glibc 2.0 */
			size *= 2;  /* twice the old size */
		if ((newbuf = (char *) realloc( buf, size )) == NULL) {
			free( buf );
			return false;
		} else {
			buf = newbuf;
		}
	}

    // Add the report
    buf2 = std::string( buf );
    m_contents [i_section] += buf2;
    // Signal the report
    m_sig_report( r_section, buf2 );

	// Free the buffer
	free( buf );

    // Write all the sections into the log
    for (size_t i=0; i<m_sections.size(); i++) {
        // Write section title
        fprintf( file, "%s:\n----------------\n", m_sections [i].c_str() );
        // Write section contents
        fprintf( file, "%s\n\n", m_contents [i].c_str() );
    }

    // And flush it into the file
	fflush( file );
    fclose( file );

    return true;
}

